package com.luych.toolbox.data.service.core.mysql;

import com.luych.toolbox.common.enums.CaseType;
import com.luych.toolbox.common.enums.DataSourceType;
import com.luych.toolbox.data.service.core.CoreBuilder;
import com.luych.toolbox.data.service.core.CoreColumn;

import java.util.Arrays;

public class MysqlColumn implements CoreColumn {

    private final String owner;
    private final String name;
    private final MysqlDataType dataType;
    private final Long charLength;
    private final Long numericPrecision;
    private final Long numericScale;
    private final Boolean nullable;
    private final String comment;
    private final Boolean increment;

    public MysqlColumn(CoreColumn coreColumn) {
        this.owner = coreColumn.getOwner();
        this.name = coreColumn.getName();
        this.dataType = (MysqlDataType) CoreBuilder.buildDataType(coreColumn.getDataSourceType(), DataSourceType.MYSQL, coreColumn.getDataType());
        this.charLength = coreColumn.getCharLength();
        this.numericPrecision = coreColumn.getNumericPrecision();
        this.numericScale = coreColumn.getNumericScale();
        this.nullable = coreColumn.isNullable();
        this.comment = coreColumn.getComment();
        this.increment = coreColumn.isIncrement();
    }

    public MysqlColumn(String owner, String name, MysqlDataType dataType, Long charLength, Long numericPrecision, Long numericScale, Boolean nullable, String comment, Boolean increment) {
        this.owner = owner;
        this.name = name;
        this.dataType = dataType;
        this.charLength = charLength;
        this.numericPrecision = numericPrecision;
        this.numericScale = numericScale;
        this.nullable = nullable;
        this.comment = comment;
        this.increment = increment;
    }

    @Override
    public DataSourceType getDataSourceType() {
        return DataSourceType.MYSQL;
    }

    @Override
    public String getOwner() {
        return owner;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public MysqlDataType getDataType() {
        return dataType;
    }

    @Override
    public String getColumnType() {
        if (Arrays.asList(MysqlDataType.FLOAT, MysqlDataType.DOUBLE).contains(this.dataType) &&
                this.numericPrecision != null && this.numericScale == null) {
            return this.dataType.getName();
        }
        return CoreColumn.super.getColumnType();
    }

    @Override
    public Long getCharLength() {
        return charLength;
    }

    @Override
    public Long getNumericPrecision() {
        return numericPrecision;
    }

    @Override
    public Long getNumericScale() {
        return numericScale;
    }

    @Override
    public Boolean isNullable() {
        return nullable;
    }

    @Override
    public String getComment() {
        return comment;
    }

    @Override
    public Boolean isIncrement() {
        return increment;
    }

    @Override
    public String getCreateSql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "`" + tableName + "`";
        columnName = "`" + columnName + "`";

        String sql = "ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + this.getColumnType();
        if (this.isIncrement()) {
            sql += " AUTO_INCREMENT";
        }
        if (this.isNullable()) {
            sql += " NULL";
        } else {
            sql += " NOT NULL";
        }
        sql += " COMMENT '" + this.getComment() + "'";
        sql += ";";
        return sql;
    }

    @Override
    public String getModifySql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "`" + tableName + "`";
        columnName = "`" + columnName + "`";

        String sql = "ALTER TABLE " + tableName + " MODIFY COLUMN " + columnName + " " + this.getColumnType();
        if (this.isIncrement()) {
            sql += " AUTO_INCREMENT";
        }
        if (this.isNullable()) {
            sql += " NULL";
        } else {
            sql += " NOT NULL";
        }
        sql += " COMMENT '" + this.getComment() + "'";
        sql += ";";
        return sql;
    }

    @Override
    public String getRemoveSql(CaseType caseType) {
        String tableName = caseType.getConvert().apply(this.getOwner());
        String columnName = caseType.getConvert().apply(this.getName());

        tableName = "`" + tableName + "`";
        columnName = "`" + columnName + "`";

        return "ALTER TABLE " + tableName + " DROP COLUMN " + columnName + ";";
    }
}
